/*
* 包含n个action creator
* 异步action
* 同步action
* */


import io from 'socket.io-client'

import {
    AUTH_SUCCESS,
    ERROR_MSG,
    RECEIVE_USER,
    RESET_USER,
    RECEIVE_USER_LIST,
    RECEIVE_MSG_LIST,
    RECEIVE_MSG,
    MSG_READ
} from './action-types'

import {
    reqRegister,
    reqLogin,
    reqUpdateUser,
    reqUser,
    reqUserList,
    reqChatMsgList,
    reqReadMsg
} from '../api'

/*
* 单例对象,只存在一个socket对象
* 1. 创建对象之前:  判断对象是否已经创建, 只有没有创建对象时,采取创建
* 2. 创建对象之后:  保存对象
* */

// socket连接的代码封装成一个函数
function initIO(dispatch, userid) {
    if (!io.socket) {
        // 连接服务器, 得到与服务器的连接对象
        // 保存对象
        io.socket = io('ws://localhost:4000')
        // 绑定监听,接受服务端发送过来的消息
        io.socket.on('receiveMsg', function (chatMsg) {
            console.log('... 客户端 <-  服务器', chatMsg)
            // 只有当chatMsg 与 当前用户相关的消息 才去 分发同步 action 保存消息
            // debugger
            if (userid===chatMsg.from || userid===chatMsg.to) {
                dispatch(receiveMsg({chatMsg, userid}))
            }
        })
    }

}

// 异步获取消息列表数据
async function getMsgList(dispatch, userid) {
    initIO(dispatch, userid)   // 初始化socket  获取连接
    // debugger
    const response = await reqChatMsgList()
    const result = response.data
    if (result.code === 0) {
        // 获取消息列表和聊天对象的数据
        const {users, chatMsgs} = result.data
        // console.log(users)
        // console.log(chatMsgs)
        // 分发同步action
        dispatch(receiveMsgList({users, chatMsgs, userid}))
    }
}



// 发送消息的异步action
export const sendMsg = ({from, to, content}) => {
    return dispatch => {
        console.log('客户端 -> 服务器 .... ', {from, to, content})

        // 发消息
        io.socket.emit('sendMsg', {from, to, content})
    }
}


// 读取消息的异步action
export const readMsg = (from, to) => {
    return async dispatch => {
        /*
        * 后台回去修改对应消息的read为true   存在数据库中的,
        * 点击读取到了这一步,那么就都是已读的消息了
        * */
        const response = await reqReadMsg(from)
        const result = response.data
        if (result.code===0) {
            const count = result.data
            dispatch(msgRead({count, from, to}))
        }
    }
}






// 请求授权成功的同步action
const authSuccess = (user) => ({type:AUTH_SUCCESS, data:user})
// 错误同步信息的同步action
const errorMsg = (msg) => ({type:ERROR_MSG, data:msg})
// 接收用户的同步action
const receiveUser = (user) => ({type:RECEIVE_USER, data:user})
// 重置用户的同步action   退出登录时需要删除user  需要调用  需要向外暴露 否则只是私有的
export const resetUser = (msg) => ({type:RESET_USER, data:msg})
// 接受用户列表 的 同步action
export const receiveUserList = (userList) => ({type: RECEIVE_USER_LIST, data:userList})

// 接收消息列表的同步action
export const receiveMsgList = ({users, chatMsgs, userid}) => ({type: RECEIVE_MSG_LIST, data: {users, chatMsgs, userid}})

// 接受一个消息的同步action
const receiveMsg = ({chatMsg, userid}) => ({type: RECEIVE_MSG, data: {chatMsg, userid}})

// 查看某个聊天消息的同步action
const msgRead = ({count, from, to}) => ({type: MSG_READ, data: {count, from, to} })





// 注册action 异步action
export const register = (user) => {


    const {username, password, password2, type} = user
    // console.log(user)

    // 做表单提交的前台验证, 如果并不通过,分发一个errorMsg()  的同步  action
    if (!username) {
        return errorMsg('用户名不能为空!!!')
    } else if (password !== password2) {
        return errorMsg('密码与确认密码不一致!!!')
    } else if(!password) {
        return  errorMsg("密码不能为空!!!")
    }



    // 表单数据合法, 返回一个发送ajax请求的异步action函数
    return async dispatch => {


        // 发送注册的异步ajax请求
        /*const promise = reqRegister(user)
        promise.then(response => {
            const result = response.data     // {code: 0/1, data: user, msg:''}
        })*/
        // 要直接有结果  就得等待   一旦有await  那么函数就要声明成 async
        const result = await reqRegister({username, password, type})


        // console.log(result)
        // const result = response.code
        if(result.data.code === 0) {
            // 成功
            // 分发成功的action
            getMsgList(dispatch, result.data._id)   // 注册成功时就需要获取消息列表
            dispatch(authSuccess(result.data))
        } else {
            // 失败
            // 分发失败的action
            dispatch(errorMsg(result.data.msg))
        }
    }
}



// 登录action 异步action
export const login = (user) => {


    const {username, password} = user

    // 做表单提交的前台验证, 如果并不通过,分发一个errorMsg()  的同步  action
    if (!username) {
        return errorMsg('用户名不能为空!!!')
    } else if(!password) {
        return  errorMsg("密码不能为空!!!")
    }


    return  async dispatch => {
        // 发送注册的异步ajax请求
        /*const promise = reqRegister(user)
        promise.then(response => {
            const result = response.data     // {code: 0/1, data: user, msg:''}
        })*/
        // 要直接有结果  就得等待   一旦有await  那么函数就要声明成 async
        const response =  await reqLogin({username, password})
        const result = response.data
        if(result.code === 0) {
            // 成功
            // 分发成功的action
            getMsgList(dispatch, result.data._id)   // 登录成功时就需要获取消息列表
            dispatch(authSuccess(result.data))
        } else {
            // 失败
            // 分发失败的action
            dispatch(errorMsg(result.msg))
        }
    }
}

// 更新用户异步action
export const updateUser = (user) => {
    // 返回的是后一个函数
    return async dispatch => {
        const response = await reqUpdateUser(user)
        const result = response.data
        if (result.code == 0) {  // 更新成功: data
            dispatch(receiveUser(result.data))
        } else {  // 更新失败 : msg
            dispatch(resetUser(result.msg))
        }
    }
}


// 获取user 的 action
export const getUser = () => {
    return async dispatch => {
        // debugger
        // 执行异步ajax请求
        const response = await reqUser()
        // console.log(response)
        const result = response.data
        console.log(result)
        if (result.code === 0) {   // 成功
            getMsgList(dispatch, result.data._id)   // 获取用户详情成功时就需要获取消息列表
            dispatch(receiveUser(result.data))
        } else {   // 失败
            dispatch(resetUser(result.msg))
        }
    }
}


// 异步请求获取用户列表
export const getUserList = (type) => {
    return async dispatch => {
        // 执行异步ajax请求
        const response = await reqUserList(type)
        const result = response.data
        // 得到结果后,分发一个同步action
        if (result.code === 0) {
            dispatch(receiveUserList(result.data))
        }
    }
}






/*包含n个action creator
异步action
同步action*/

